<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>SpringBoot | 浪飞IT小栈</title>
    <meta name="generator" content="VuePress 1.9.9">
    <link rel="icon" href="/img/favicon.ico">
    <meta name="description" content="前后端技术分享">
    <meta name="keywords" content="前端博客,后端博客,人工智能,个人技术博客,前端,前端开发,前端框架,web前端,前端面试题,技术文档,学习,面试,JavaScript,js,ES6,TypeScript,vue,python,css3,html5,Node,git,github,markdown,java,Spring,Springboot,Redis,mysql">
    <meta name="baidu-site-verification" content="7F55weZDDc">
    <meta name="theme-color" content="#11a8cd">
    
    <link rel="preload" href="/assets/css/0.styles.ada71c49.css" as="style"><link rel="preload" href="/assets/js/app.a2a00aa5.js" as="script"><link rel="preload" href="/assets/js/2.256f807a.js" as="script"><link rel="preload" href="/assets/js/53.4110ef1e.js" as="script"><link rel="prefetch" href="/assets/js/10.ab144fe3.js"><link rel="prefetch" href="/assets/js/11.062e0879.js"><link rel="prefetch" href="/assets/js/12.f9c60882.js"><link rel="prefetch" href="/assets/js/13.0a6ebfcf.js"><link rel="prefetch" href="/assets/js/14.03fc6f12.js"><link rel="prefetch" href="/assets/js/15.19dbf9fd.js"><link rel="prefetch" href="/assets/js/16.6e68160b.js"><link rel="prefetch" href="/assets/js/17.1d678834.js"><link rel="prefetch" href="/assets/js/18.4536fd5c.js"><link rel="prefetch" href="/assets/js/19.9c1b65df.js"><link rel="prefetch" href="/assets/js/20.c5f96e71.js"><link rel="prefetch" href="/assets/js/21.3f0b334e.js"><link rel="prefetch" href="/assets/js/22.55c868be.js"><link rel="prefetch" href="/assets/js/23.91286241.js"><link rel="prefetch" href="/assets/js/24.c1af1909.js"><link rel="prefetch" href="/assets/js/25.a995a755.js"><link rel="prefetch" href="/assets/js/26.abc5dea3.js"><link rel="prefetch" href="/assets/js/27.1eb62850.js"><link rel="prefetch" href="/assets/js/28.b383a871.js"><link rel="prefetch" href="/assets/js/29.088e0d73.js"><link rel="prefetch" href="/assets/js/3.cd716564.js"><link rel="prefetch" href="/assets/js/30.3ccc98d5.js"><link rel="prefetch" href="/assets/js/31.aab7cc23.js"><link rel="prefetch" href="/assets/js/32.5e16b7e6.js"><link rel="prefetch" href="/assets/js/33.4aaeb741.js"><link rel="prefetch" href="/assets/js/34.45e8e898.js"><link rel="prefetch" href="/assets/js/35.5899c97a.js"><link rel="prefetch" href="/assets/js/36.32e2e263.js"><link rel="prefetch" href="/assets/js/37.c4e27bbd.js"><link rel="prefetch" href="/assets/js/38.fe5e60d2.js"><link rel="prefetch" href="/assets/js/39.2cb0b4ee.js"><link rel="prefetch" href="/assets/js/4.edf4d5e7.js"><link rel="prefetch" href="/assets/js/40.08d5bead.js"><link rel="prefetch" href="/assets/js/41.2f80f24b.js"><link rel="prefetch" href="/assets/js/42.43a49913.js"><link rel="prefetch" href="/assets/js/43.08da7ec2.js"><link rel="prefetch" href="/assets/js/44.7c7cb8a9.js"><link rel="prefetch" href="/assets/js/45.0ddf7e7f.js"><link rel="prefetch" href="/assets/js/46.7c4609a5.js"><link rel="prefetch" href="/assets/js/47.edf3ddf8.js"><link rel="prefetch" href="/assets/js/48.569a90b9.js"><link rel="prefetch" href="/assets/js/49.fa368ac8.js"><link rel="prefetch" href="/assets/js/5.24054156.js"><link rel="prefetch" href="/assets/js/50.b9b3ea7f.js"><link rel="prefetch" href="/assets/js/51.a2ebf0fe.js"><link rel="prefetch" href="/assets/js/52.31f02238.js"><link rel="prefetch" href="/assets/js/54.dab741c7.js"><link rel="prefetch" href="/assets/js/55.f27984e9.js"><link rel="prefetch" href="/assets/js/56.bd4c1a8e.js"><link rel="prefetch" href="/assets/js/57.375d40cb.js"><link rel="prefetch" href="/assets/js/58.932e3864.js"><link rel="prefetch" href="/assets/js/59.e657be1b.js"><link rel="prefetch" href="/assets/js/6.b259c061.js"><link rel="prefetch" href="/assets/js/60.88d94274.js"><link rel="prefetch" href="/assets/js/61.fa71d884.js"><link rel="prefetch" href="/assets/js/62.a9d3b3b7.js"><link rel="prefetch" href="/assets/js/63.f849fe75.js"><link rel="prefetch" href="/assets/js/64.1770f7a9.js"><link rel="prefetch" href="/assets/js/65.6afc33db.js"><link rel="prefetch" href="/assets/js/66.799f2eb4.js"><link rel="prefetch" href="/assets/js/67.f36b2f7d.js"><link rel="prefetch" href="/assets/js/68.868cd00b.js"><link rel="prefetch" href="/assets/js/69.4c29b907.js"><link rel="prefetch" href="/assets/js/7.e34ea00f.js"><link rel="prefetch" href="/assets/js/70.1b993ed4.js"><link rel="prefetch" href="/assets/js/71.e16ad4f9.js"><link rel="prefetch" href="/assets/js/72.627505e6.js"><link rel="prefetch" href="/assets/js/73.32768e14.js"><link rel="prefetch" href="/assets/js/74.968a580d.js"><link rel="prefetch" href="/assets/js/75.42d5af3d.js"><link rel="prefetch" href="/assets/js/76.19a69d31.js"><link rel="prefetch" href="/assets/js/77.cf627a78.js"><link rel="prefetch" href="/assets/js/78.07177880.js"><link rel="prefetch" href="/assets/js/8.c4dd00ce.js"><link rel="prefetch" href="/assets/js/9.0ff73be2.js">
    <link rel="stylesheet" href="/assets/css/0.styles.ada71c49.css">
  </head>
  <body class="theme-mode-light">
    <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/img/logo.png" alt="浪飞IT小栈" class="logo"> <span class="site-name can-hide">浪飞IT小栈</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/pages/6138ae/" class="nav-link">Java速通</a></div><div class="nav-item"><a href="/pages/705b35/" class="nav-link">面试经典</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="精品项目" class="dropdown-title"><a href="/project/" class="link-title">精品项目</a> <span class="title" style="display:none;">精品项目</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>桌面端</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/pages/8143cc480faf9a11/" class="nav-link">JavaScript</a></li></ul></li><li class="dropdown-item"><h4>PC后端</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/note/javascript/" class="nav-link">项目1</a></li><li class="dropdown-subitem"><a href="/note/typescript-axios/" class="nav-link">项目二</a></li></ul></li></ul></div></div><div class="nav-item"><a href="/about/" class="nav-link">电子书</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">归档</a></li></ul></div></div><div class="nav-item"><a href="/pages/0c07b2/" class="nav-link">IT杂货铺</a></div><div class="nav-item"><a href="/archives/" class="nav-link">更多资源</a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><div class="blogger"><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/avatar.jpg"> <div class="blogger-info"><h3>浪飞yes</h3> <span>无法简单的人儿~</span></div></div> <nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/pages/6138ae/" class="nav-link">Java速通</a></div><div class="nav-item"><a href="/pages/705b35/" class="nav-link">面试经典</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="精品项目" class="dropdown-title"><a href="/project/" class="link-title">精品项目</a> <span class="title" style="display:none;">精品项目</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>桌面端</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/pages/8143cc480faf9a11/" class="nav-link">JavaScript</a></li></ul></li><li class="dropdown-item"><h4>PC后端</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/note/javascript/" class="nav-link">项目1</a></li><li class="dropdown-subitem"><a href="/note/typescript-axios/" class="nav-link">项目二</a></li></ul></li></ul></div></div><div class="nav-item"><a href="/about/" class="nav-link">电子书</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">归档</a></li></ul></div></div><div class="nav-item"><a href="/pages/0c07b2/" class="nav-link">IT杂货铺</a></div><div class="nav-item"><a href="/archives/" class="nav-link">更多资源</a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>开篇</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>基础语法</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>面向对象</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>常用类</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>基础高级</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>数据库</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>前端技术</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>热门框架</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/pages/71d587/" class="sidebar-link">Maven</a></li><li><a href="/pages/1b0493/" class="sidebar-link">MySQL加强</a></li><li><a href="/pages/712f3f/" class="sidebar-link">MyBatis加强</a></li><li><a href="/pages/78eb56/" class="sidebar-link">MyBatis-Plus</a></li><li><a href="/pages/bbdeaa/" class="sidebar-link">Spring框架</a></li><li><a href="/pages/8bb4cd/" class="sidebar-link">SpringMVC框架</a></li><li><a href="/pages/4ab4d3/" class="sidebar-link">项目实战-SSM整合</a></li><li><a href="/pages/de0eaa/" aria-current="page" class="active sidebar-link">SpringBoot</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#一、今日学习内容与目标" class="sidebar-link">一、今日学习内容与目标</a></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#二、javaconfig" class="sidebar-link">二、JavaConfig</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_2-1-xml-方式配置-ioc" class="sidebar-link">2.1 XML 方式配置 IoC</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_2-2-javaconfig-方式配置-ioc" class="sidebar-link">2.2 JavaConfig 方式配置 IoC</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_2-3-xml-方式配置-di" class="sidebar-link">2.3 XML 方式配置 DI</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_2-4-javaconfig-方式配置-di" class="sidebar-link">2.4 JavaConfig 方式配置 DI</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_2-4-1-通过方法形参注入" class="sidebar-link">2.4.1 通过方法形参注入</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_2-4-2-调用方法注入" class="sidebar-link">2.4.2 调用方法注入</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_2-5-使用-ioc-di-注解简化配置" class="sidebar-link">2.5 使用 IoC DI 注解简化配置</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_2-6-spring-test-方式加载配置类" class="sidebar-link">2.6 Spring Test 方式加载配置类</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_2-6-1-junit4-的方式" class="sidebar-link">2.6.1 JUnit4 的方式</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_2-6-2-junit5-的方式" class="sidebar-link">2.6.2 JUnit5 的方式</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_2-7-配置类的导入" class="sidebar-link">2.7 配置类的导入</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_2-7-1-xml-方式" class="sidebar-link">2.7.1 XML 方式</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_2-7-2-配置类方式" class="sidebar-link">2.7.2 配置类方式</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_2-7-3-配置类导入-xml-配置" class="sidebar-link">2.7.3 配置类导入 XML 配置</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#三、spring-boot-介绍" class="sidebar-link">三、Spring Boot 介绍</a></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#四、spring-boot-快速入门" class="sidebar-link">四、Spring Boot 快速入门</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_4-1-入门案例" class="sidebar-link">4.1 入门案例</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_4-2-疑问" class="sidebar-link">4.2 疑问</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#五、入门案例分析" class="sidebar-link">五、入门案例分析</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_5-1-spring-boot-starter-parent" class="sidebar-link">5.1 spring-boot-starter-parent</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_5-2-spring-boot-starter" class="sidebar-link">5.2 Spring Boot Starter</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_5-3-web-启动器" class="sidebar-link">5.3 Web 启动器</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_5-4-打包独立运行" class="sidebar-link">5.4 打包独立运行</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#六、spring-boot-参数配置" class="sidebar-link">六、Spring Boot 参数配置</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_6-1-参数来源" class="sidebar-link">6.1 参数来源</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_6-1-1-application-properties" class="sidebar-link">6.1.1 application.properties</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_6-1-2-application-yml" class="sidebar-link">6.1.2 application.yml</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_6-2-配置优先级-了解" class="sidebar-link">6.2 配置优先级（了解）</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_6-3-参数属性绑定" class="sidebar-link">6.3 参数属性绑定</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_6-3-1-自定义的-properties" class="sidebar-link">6.3.1 自定义的 properties</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_6-3-2-默认application-properties" class="sidebar-link">6.3.2 默认application.properties</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_6-3-3-environment-对象绑定属性" class="sidebar-link">6.3.3 Environment 对象绑定属性</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#七、spring-boot-实战" class="sidebar-link">七、Spring Boot 实战</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-1-迁移-ssm-项目" class="sidebar-link">7.1 迁移 ssm 项目</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-2-配置数据库连接池" class="sidebar-link">7.2 配置数据库连接池</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-2-1-添加依赖" class="sidebar-link">7.2.1 添加依赖</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-2-2-自动配置方式" class="sidebar-link">7.2.2 自动配置方式</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-2-3-配置-druid-连接池" class="sidebar-link">7.2.3 配置 Druid 连接池</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-3-集成-mybatis和pagehelper" class="sidebar-link">7.3 集成 MyBatis和PageHelper</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-3-1-拷贝项目代码" class="sidebar-link">7.3.1 拷贝项目代码</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-3-2-添加依赖" class="sidebar-link">7.3.2 添加依赖</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-3-3-配置-mapper-对象" class="sidebar-link">7.3.3 配置 Mapper 对象</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-3-4-配置属性" class="sidebar-link">7.3.4 配置属性</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-4-事务管理" class="sidebar-link">7.4 事务管理</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-4-1-xml方式-了解" class="sidebar-link">7.4.1 XML方式（了解）</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-4-2-注解方式" class="sidebar-link">7.4.2 注解方式</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-4-3-配置代理实现" class="sidebar-link">7.4.3 配置代理实现</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-4-4-测试验证" class="sidebar-link">7.4.4 测试验证</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-5-集成-web" class="sidebar-link">7.5 集成 Web</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-5-1-添加依赖" class="sidebar-link">7.5.1 添加依赖</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-5-2-修改端口" class="sidebar-link">7.5.2 修改端口</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-5-3-静态资源处理" class="sidebar-link">7.5.3 静态资源处理</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-6-集成-jsp" class="sidebar-link">7.6 集成 JSP</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-6-1-添加依赖" class="sidebar-link">7.6.1 添加依赖</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-6-2-定义jsp存储目录" class="sidebar-link">7.6.2 定义JSP存储目录</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-6-3-相关配置" class="sidebar-link">7.6.3 相关配置</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-6-4-controller配置" class="sidebar-link">7.6.4 Controller配置</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-7-统一异常处理" class="sidebar-link">7.7 统一异常处理</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-7-1-框架自带方式" class="sidebar-link">7.7.1 框架自带方式</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-7-2-控制器增强器方式" class="sidebar-link">7.7.2 控制器增强器方式</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_7-8-添加拦截器" class="sidebar-link">7.8 添加拦截器</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-8-1-编写拦截器" class="sidebar-link">7.8.1 编写拦截器</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_7-8-2-配置义拦截器" class="sidebar-link">7.8.2 配置义拦截器</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#八、系统日志" class="sidebar-link">八、系统日志</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_8-1-为什么要用日志" class="sidebar-link">8.1 为什么要用日志</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_8-2-spring-boot-中的日志介绍" class="sidebar-link">8.2 Spring Boot 中的日志介绍</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_8-3-输出日志" class="sidebar-link">8.3 输出日志</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_8-4-日志级别" class="sidebar-link">8.4 日志级别</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_8-5-logback-配置文件的使用" class="sidebar-link">8.5 Logback 配置文件的使用</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#九、其他功能" class="sidebar-link">九、其他功能</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_9-1-修改-banner" class="sidebar-link">9.1 修改 banner</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_9-2-切换运行环境" class="sidebar-link">9.2 切换运行环境</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#十、spring-boot-自动配置原理" class="sidebar-link">十、Spring Boot 自动配置原理</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_10-1-springbootapplication" class="sidebar-link">10.1 @SpringBootApplication</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_10-1-1-springbootconfiguration" class="sidebar-link">10.1.1 @SpringBootConfiguration</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_10-1-2-componentscan" class="sidebar-link">10.1.2 @ComponentScan</a></li><li class="sidebar-sub-header level4"><a href="/pages/de0eaa/#_10-1-3-enableautoconfiguration" class="sidebar-link">10.1.3 @EnableAutoConfiguration</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_10-2-如何自动配置" class="sidebar-link">10.2 如何自动配置</a></li><li class="sidebar-sub-header level3"><a href="/pages/de0eaa/#_10-3-总结" class="sidebar-link">10.3 总结</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/de0eaa/#十一、小结与作业" class="sidebar-link">十一、小结与作业</a></li></ul></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>前后端分离</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>权限控制</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>NoSQL</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>微服务</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>消息中间件</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>脚手架</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>技术增值</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="articleInfo-wrap" data-v-06225672><div class="articleInfo" data-v-06225672><ul class="breadcrumbs" data-v-06225672><li data-v-06225672><a href="/" title="首页" class="iconfont icon-home router-link-active" data-v-06225672></a></li> <li data-v-06225672><a href="/categories/?category=Java%E9%80%9F%E9%80%9A" title="分类" data-v-06225672>Java速通</a></li><li data-v-06225672><a href="/categories/?category=%E7%83%AD%E9%97%A8%E6%A1%86%E6%9E%B6" title="分类" data-v-06225672>热门框架</a></li></ul> <div class="info" data-v-06225672><div title="作者" class="author iconfont icon-touxiang" data-v-06225672><a href="https://github.com/langfeiyes" target="_blank" title="作者" class="beLink" data-v-06225672>langfeiyes</a></div> <div title="创建时间" class="date iconfont icon-riqi" data-v-06225672><a href="javascript:;" data-v-06225672>2024-03-10</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-title">目录</div> <div class="right-menu-content"></div></div></div> <h1><img src="">SpringBoot<!----></h1>  <div class="theme-vdoing-content content__default"><h1 id="spring-boot"><a href="#spring-boot" class="header-anchor">#</a> Spring Boot</h1> <p><strong><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/springboot.png" alt=""></strong></p> <h2 id="一、今日学习内容与目标"><a href="#一、今日学习内容与目标" class="header-anchor">#</a> 一、今日学习内容与目标</h2> <ul><li>了解 Java 配置的优势。</li> <li>掌握 Java 配置的使用。</li> <li>理解 Spring Boot 的作用。</li> <li>掌握 Spring Boot 的使用。</li> <li>掌握 Spring Boot 属性绑定。</li></ul> <h2 id="二、javaconfig"><a href="#二、javaconfig" class="header-anchor">#</a> 二、JavaConfig</h2> <p>我们通常使用 Spring 都会使用 XML 配置，随着功能以及业务逻辑的日益复杂，应用伴随着大量的 XML 配置文件以及复杂的 bean 依赖关系，使用起来很不方便。</p> <p>在 Spring 3.0 开始，Spring 官方就已经开始推荐使用 Java 配置来代替传统的 XML 配置了，它允许开发者将 bean 的定义和 Spring 的配置编写到到 Java 类中，不过似乎在国内并未推广盛行。当 Spring Boot 来临，人们才慢慢认识到 Java 配置的优雅，但是，也仍然允许使用经典的 XML 方式来定义 bean 和 配置 Spring。其有以下优势：</p> <ul><li>面向对象的配置。由于配置被定义为 JavaConfig 中的类，因此用户可以充分使用 Java 中的面向对象功能。一个配置类可以继承另一个，重写它的 @Bean 方法等。</li> <li>减少或者消除 XML 配置。提供了一种纯 Java 的方式来配置与 XML 配置概念相似的 Spring 容器。</li> <li>类型安全和重构友好。提供了一种类型安全的方法了来配置 Spring 容器，由于 Java 5 对泛型的支持，现在可以按类型而不是名称检索 bean，不需要任何的强制转换或者基于字符串的查找。</li></ul> <p>进行下面学习先搭建一个基于 Maven 构建的项目 java-config-demo，添加如下依赖：</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-context<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>5.0.8.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h3 id="_2-1-xml-方式配置-ioc"><a href="#_2-1-xml-方式配置-ioc" class="header-anchor">#</a> 2.1 XML 方式配置 IoC</h3> <p><strong>定义两个 Bean</strong></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SomeBean</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">OtherBean</span> otherBean<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setOtherBean</span><span class="token punctuation">(</span><span class="token class-name">OtherBean</span> otherBean<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>otherBean <span class="token operator">=</span> otherBean<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">public</span> <span class="token class-name">SomeBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;SomeBean 被创建&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;SomeBean 被初始化&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">destroy</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;SomeBean 被销毁&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">// 省略 toString 方法</span>
<span class="token punctuation">}</span>

<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">OtherBean</span> <span class="token punctuation">{</span> 
    <span class="token keyword">public</span> <span class="token class-name">OtherBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;OtherBean 被创建&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><p><strong>编写配置</strong></p> <p>在 XML 配置文件中去配置这些 Bean 交给 Spring 管理。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- applicationContext.xml --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>someBean<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cn.wolfcode.bean.SomeBean<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p><strong>启动 Spring</strong></p> <p>启动 Spring 读取该 XML 文件创建容器对象，从容器中获取 SomeBean 对象。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IoCTest</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">testXmlConfig</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">ApplicationContext</span> ctx <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ClassPathXmlApplicationContexnt</span><span class="token punctuation">(</span><span class="token string">&quot;classpath:applicationContext.xml&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">SomeBean</span> someBean <span class="token operator">=</span> ctx<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token class-name">SomeBean</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>someBean<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h3 id="_2-2-javaconfig-方式配置-ioc"><a href="#_2-2-javaconfig-方式配置-ioc" class="header-anchor">#</a> 2.2 JavaConfig 方式配置 IoC</h3> <p>JavaConfig 方式中使用注解彻底的替代 XML 文件，那么到底要怎么告诉 Spring 容器，bean 没有定义在 XML 文件中，而是定义在一个 Java 配置类中。</p> <ul><li><code>@Configuration</code>：在类上贴该注解表示该类是 Spring 的配置类，具有 applicationContext.xml 文件的作用。</li> <li><code>@Bean</code>：在 Spring 的配置类的方法上贴该注解后，该方法返回的对象会交给 Spring 容器管理，替代 applicationContext.xml 中的 bean 标签。</li> <li><code>@ComponentScan</code>：在 Spring 配置类上贴该注解表示开启组件扫描器，默认扫描当前配置类所在的包，也可以自己指定，替代 XML 配置中的 <code>&lt;context:component-scan /&gt;</code> 标签。</li> <li><code>AnnotationConfigApplicationContext</code>：该类是 ApplicationContext 接口的实现类，该对象是基于 JavaConfig 的方式来运作的 Spring 容器。</li></ul> <p><strong>定义一个配置类</strong></p> <p>替代之前的 XML 文件，类中定义方法，返回 bean 对象交给 Spring 管理。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">/**
* @Configuration
* 贴有该注解的类表示 Spring 的配置类
* 用于替代传统的 applicationContext.xml
*/</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span> 
    
    <span class="token comment">/**
    * @Bean
    * 该注解贴在配置类的方法上，该方法会被 Spring 容器自动调用
    * 并且返回的对象交给 Spring 管理
    * 相当于 &lt;bean id=&quot;someBean&quot; class=&quot;cn.wolfcode.bean.SomeBean&quot;/&gt;
    */</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">SomeBean</span> <span class="token function">someBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">SomeBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><p><strong>启动 Spring</strong></p> <p>加载配置类，启动 AnnotationConfigApplicationContext 容器对象，测试效果。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IoCTest</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">testJavaConfig</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 加载配置类，创建 Spring 容器</span>
        <span class="token class-name">ApplicationContext</span> ctx <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AnnotationConfigApplicationContext</span><span class="token punctuation">(</span><span class="token class-name">JavaConfig</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// 从容器中取出 SomeBean 对象</span>
        <span class="token class-name">SomeBean</span> someBean <span class="token operator">=</span> ctx<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token class-name">SomeBean</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>someBean<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p><strong>@Bean 注解中的属性</strong></p> <p>在 XML 配置 bean 的方式中，我们可以在 bean 标签中的 id，name，init-method，destroy-method，scope 等属性来完成对应的配置，在使用 JavaConfig 方式中我们也一样能通过相应的配置来完成同样的效果，这些效果大多封装到 @Bean 注解的属性中。@Bean 注解中的属性有以下：</p> <ul><li>name：对应 bean 标签中的 name 属性，用于给 bean 取别名；</li> <li>initMethod：对应 bean 标签中的 init-method 属性，配置 bean 的初始化方法；</li> <li>destroyMethod：对应 bean 标签中的 destroy-method 属性，配置 bean 的销毁方法。</li></ul> <p>注意：在配置类的方式中有许多的默认规定，比如：</p> <ul><li><strong>bean 的 id 就是当前方法名</strong>；</li> <li>配置多例则是在方法上添加 <code>@Scope(&quot;prototype&quot;)</code> 注解来实现，一般不用配，默认单例即可。</li></ul> <h3 id="_2-3-xml-方式配置-di"><a href="#_2-3-xml-方式配置-di" class="header-anchor">#</a> 2.3 XML 方式配置 DI</h3> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>someBean<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cn.wolfcode.bean.someBean<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>otherBean<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>otherBean<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>bean</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>otherBean<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cn.wolfcode.bean.OtherBean<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h3 id="_2-4-javaconfig-方式配置-di"><a href="#_2-4-javaconfig-方式配置-di" class="header-anchor">#</a> 2.4 JavaConfig 方式配置 DI</h3> <p>在配置类方式中我们有两种方式可以完成依赖注入，无论是哪种方式，前提都是要先把 bean 交给 Spring 管理，然后在把 bean 注入过去后再使用 setter 方法设置关系。通用步骤：先把两个 bean 交给 Spring 管理。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">SomeBean</span> <span class="token function">someBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">SomeBean</span> someBean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SomeBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> someBean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">OtherBean</span> <span class="token function">otherBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">OtherBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h4 id="_2-4-1-通过方法形参注入"><a href="#_2-4-1-通过方法形参注入" class="header-anchor">#</a> 2.4.1 通过方法形参注入</h4> <p>把需要注入的 bean 对象作为参数传入到另一个 bean 的方法声明中，形参名称最好跟 bean 的 id 一致。在容器里面有的 bean，都可以用这种方式注入。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">// 在声明 SomeBean 的方法形参中直接注入 OtherBean 对象</span>
<span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">SomeBean</span> <span class="token function">someBean</span><span class="token punctuation">(</span><span class="token class-name">OtherBean</span> otherBean<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">SomeBean</span> someBean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SomeBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    someBean<span class="token punctuation">.</span><span class="token function">setOtherBean</span><span class="token punctuation">(</span>otherBean<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> someBean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h4 id="_2-4-2-调用方法注入"><a href="#_2-4-2-调用方法注入" class="header-anchor">#</a> 2.4.2 调用方法注入</h4> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">// 调用上面已经声明的 otherBean 方法 </span>
<span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">SomeBean</span> <span class="token function">someBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">SomeBean</span> someBean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SomeBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    someBean<span class="token punctuation">.</span><span class="token function">setOtherBean</span><span class="token punctuation">(</span><span class="token function">otherBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> someBean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>原理：Spring 容器在调用实例方法时，根据方法返回对象类型，判断容器中是否已经存在该类型的实例对象，如果不存在则执行实例方法，将返回对象实例交给容器管理，如果该实例已经存在了，直接从容器中拿已经存在实例对象方法，不执行实例方法。</p> <h3 id="_2-5-使用-ioc-di-注解简化配置"><a href="#_2-5-使用-ioc-di-注解简化配置" class="header-anchor">#</a> 2.5 使用 IoC DI 注解简化配置</h3> <p>以上案例中，在配置类内部去定义方法返回 bean 对象交给 Spring 管理的方式存在一个问题，就是如果需要创建的 bean 很多的话，那么就需要定义很多的方法，会导致配置类比较累赘，使用起来不方便。以前可以通过注解简化 XML 配置，现在同样也可以通过注解简化 JavaConfig，这里需要使用到 @ComponentScan 注解，等价于之前 XML 配置的 <code>&lt;context:component-scan base-package=&quot;贴了 IoC DI 注解的类所在的包&quot;/&gt;</code>。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@ToString</span>
<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SomeBean</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">OtherBean</span> otherBean<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@AutoWired</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setOtherBean</span><span class="token punctuation">(</span><span class="token class-name">OtherBean</span> otherBean<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>otherBean <span class="token operator">=</span> otherBean<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">public</span> <span class="token class-name">SomeBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;SomeBean 被创建&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;SomeBean 被初始化&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">destroy</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;SomeBean 被销毁&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">OtherBean</span> <span class="token punctuation">{</span> 
    <span class="token keyword">public</span> <span class="token class-name">OtherBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;OtherBean 被创建&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div><div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- applicationContext.xml  --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">context:</span>component-scan</span> <span class="token attr-name">base-package</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cn.wolfcode.bean<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span> <span class="token comment">// 表示该类是 Spring 的配置类</span>
<span class="token annotation punctuation">@ComponentScan</span> <span class="token comment">// 开启组件扫描器，默认扫描当前类所在的包，及其子包</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>若需要扫描的包不是配置类所在的包时，我们可以通过注解中的 value 属性来修改扫描的包。</p> <p>注意：组件扫描的方式只能扫描我们自己写的组件，若某个 bean 不是我们写的，则还是要通过在配置类中定义方法来处理，两者是可以同时存在的。</p> <h3 id="_2-6-spring-test-方式加载配置类"><a href="#_2-6-spring-test-方式加载配置类" class="header-anchor">#</a> 2.6 Spring Test 方式加载配置类</h3> <p>首先在 pom.xml 添加如下依赖：</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-test<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>5.0.8.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>test<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>4.12<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>test<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.junit.jupiter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>junit-jupiter-api<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>5.6.3<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>test<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h4 id="_2-6-1-junit4-的方式"><a href="#_2-6-1-junit4-的方式" class="header-anchor">#</a> 2.6.1 JUnit4 的方式</h4> <p><strong>基于 XML</strong></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RunWith</span><span class="token punctuation">(</span><span class="token class-name">SpringJUnit4ClassRunner</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ContextConfiguration</span><span class="token punctuation">(</span><span class="token string">&quot;classpath:XML文件路径&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IoCTest</span> <span class="token punctuation">{</span> 
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">SomeBean</span> someBean<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>someBean<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p><strong>基于配置类</strong></p> <p><code>@ContextConfiguration</code> 注解不仅支持 XML 方式启动 Spring 测试，也支持配置类的方式，配置 classes 属性来指定哪些类是配置类即可。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RunWith</span><span class="token punctuation">(</span><span class="token class-name">SpringJUnit4ClassRunner</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ContextConfiguration</span><span class="token punctuation">(</span>classes<span class="token operator">=</span><span class="token punctuation">{</span>配置类<span class="token number">1.</span><span class="token keyword">class</span><span class="token punctuation">,</span> 配置类<span class="token number">2.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IoCTest</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">SomeBean</span> someBean<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>someBean<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h4 id="_2-6-2-junit5-的方式"><a href="#_2-6-2-junit5-的方式" class="header-anchor">#</a> 2.6.2 JUnit5 的方式</h4> <p>注意测试类和测试方法都不用 public 修饰，测试类只需要贴 <code>@SpringJUnitConfig</code> 指定加载的配置即可。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@SpringJUnitConfig</span><span class="token punctuation">(</span>配置类<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">class</span> <span class="token class-name">IoCTest</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">SomeBean</span> someBean<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>someBean<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><h3 id="_2-7-配置类的导入"><a href="#_2-7-配置类的导入" class="header-anchor">#</a> 2.7 配置类的导入</h3> <p>在 Spring 项目中一般都会有多个 Spring 的配置文件，分别配置不同的组件，最后关联到主配置文件中，该功能也是同样可以在配置类的方式中使用的。</p> <h4 id="_2-7-1-xml-方式"><a href="#_2-7-1-xml-方式" class="header-anchor">#</a> 2.7.1 XML 方式</h4> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- 例如 mvc.xml 中导入 applicationContext.xml --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>import</span> <span class="token attr-name">resource</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>classpath：applicationContext.xml<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h4 id="_2-7-2-配置类方式"><a href="#_2-7-2-配置类方式" class="header-anchor">#</a> 2.7.2 配置类方式</h4> <p>需要使用 <code>@Import</code> 来完成，指定导入的配置类。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">// 主配置类</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token class-name">OtherJavaConfig</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token comment">// 在主配置类中关联次配置类</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

<span class="token comment">// 次配置类</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">OtherJavaConfig</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

<span class="token comment">// 测试</span>
<span class="token annotation punctuation">@SpringJUnitConfig</span><span class="token punctuation">(</span>classes <span class="token operator">=</span> <span class="token class-name">JavaConfig</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token comment">// 加载主配置类</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IoCTest</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h4 id="_2-7-3-配置类导入-xml-配置"><a href="#_2-7-3-配置类导入-xml-配置" class="header-anchor">#</a> 2.7.3 配置类导入 XML 配置</h4> <p>需要使用 <code>@ImportResource</code> 来完成，指定导入 XML 配置文件的路径。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">// 主配置类</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@ImportResource</span><span class="token punctuation">(</span><span class="token string">&quot;classpath:XML文件路径&quot;</span><span class="token punctuation">)</span> <span class="token comment">// 在主配置类中关联 XML 配置</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

<span class="token comment">// 测试</span>
<span class="token annotation punctuation">@SpringJUnitConfig</span><span class="token punctuation">(</span>classes <span class="token operator">=</span> <span class="token class-name">JavaConfig</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token comment">// 加载主配置类</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IoCTest</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h2 id="三、spring-boot-介绍"><a href="#三、spring-boot-介绍" class="header-anchor">#</a> 三、Spring Boot 介绍</h2> <p><a href="https%EF%BC%9A//baike.baidu.com/item/Spring%20Boot/20249767?fr=aladdin">Spring Boot</a> 是由 Pivotal 团队提供的全新框架，其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。</p> <p>人们把 Spring Boot 称为搭建程序的<code>脚手架</code>。其最主要作用就是帮我们快速的构建庞大的 Spring 项目，并且尽可能的减少一切 XML 配置，做到开箱即用，迅速上手，让我们关注与业务而非配置。</p> <p>该框架非常火，目前新开项目几乎都是基于 Spring Boot 搭建，非常符合微服务架构要求，企业招聘大多都要求有 Spring Boot 开发经验，属于面试必问的点。</p> <p><strong>优点</strong></p> <ul><li>创建独立运行的 Spring 应用程序；</li> <li>可嵌入 Tomcat，无需部署 war 文件；</li> <li>简化 Maven 配置；</li> <li>自动配置 Spring；</li> <li>提供生产就绪型功能，如：日志，健康检查和外部配置等；</li> <li>不要求配置 XML；</li> <li>非常容易和第三方框架集成起来。</li></ul> <p><strong>缺点</strong></p> <ul><li>版本更新较快，可能出现较大变化；</li> <li>因为约定大于配置，所以经常会出现一些很难解决的问题。</li></ul> <h2 id="四、spring-boot-快速入门"><a href="#四、spring-boot-快速入门" class="header-anchor">#</a> 四、Spring Boot 快速入门</h2> <h3 id="_4-1-入门案例"><a href="#_4-1-入门案例" class="header-anchor">#</a> 4.1 入门案例</h3> <p><strong>添加依赖</strong></p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- 打包方式 jar --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>packaging</span><span class="token punctuation">&gt;</span></span>jar<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>packaging</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.3.3.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependencies</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependencies</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p><strong>编写 Controller 代码</strong></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Controller</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/hello&quot;</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">hello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token string">&quot;Hello Spring Boot&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p><strong>编写启动程序</strong></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DemoApplication</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">DemoApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>然后通过 main 方法启动程序，观察控制台输出内容，最后浏览器中输入 http://localhost:8080/hello 验证效果。</p> <h3 id="_4-2-疑问"><a href="#_4-2-疑问" class="header-anchor">#</a> 4.2 疑问</h3> <ul><li>当前项目继承的 spring-boot-starter-parent 项目有什么用？
<ul><li>管理SpringBoot中需要用到的版本.</li></ul></li> <li>导入的依赖 spring-boot-starter-web 有什么用？
<ul><li>导入spring-web的依赖，内置Tomcat，内部自动配置SpringMVC哪些配置</li> <li>SpringBoot基于SpringMVC,接收请求，处理请求，响应请求.</li></ul></li> <li>占用 8080 端口的 Tomcat9 服务器哪来的？
<ul><li>引入spring-web的依赖，内置Tomcat，运行程序的时候，启动将项目部署到内置的tomcat，我们就可以直接访问了.</li></ul></li> <li>之前的 Web 应用打包是 war，为什么现在的打包方式是 jar？
<ul><li>先把项目打包成war,把war包放入到外部的Tomcat进行运行</li> <li>由于SpringBoot有内置Tomcat,不需要打包成war. 直接打包成jar,可以在命令行java -jar 运行程序，启动柜启动内置的Tomcat</li></ul></li> <li>@SpringBootApplication 注解有什么用？
<ul><li>这个注解内置@ComponentScan，当没有指定目录的时候，默认扫描当前包及其子包.</li> <li>这个注解内置@SpringBootConfiguration，又包含@Configuration, 标记当前类为SpringBoot中配置类</li></ul></li> <li>main 方法中执行的代码 SpringApplication.run(..) 有什么用？
<ul><li>读取配置文件，扫描包，自动进行配置（还没有降到）</li></ul></li></ul> <h2 id="五、入门案例分析"><a href="#五、入门案例分析" class="header-anchor">#</a> 五、入门案例分析</h2> <h3 id="_5-1-spring-boot-starter-parent"><a href="#_5-1-spring-boot-starter-parent" class="header-anchor">#</a> 5.1 spring-boot-starter-parent</h3> <p>Spring Boot 提供了一个名为 spring-boot-starter-parent 的工程，里面已经对各种常用依赖（并非全部）的版本进行了管理，我们的项目需要以这个项目为父工程，这样我们就不用操心依赖的版本问题了，需要什么依赖，直接引入坐标即可！</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.3.3.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>继承是 Maven 中很强大的一种功能，继承可以使得子 pom 可以获得 parent 中的部分配置（groupId，version，dependencies，build，dependencyManagement 等），可以对子 pom 进行统一的配置和依赖管理。</p> <ul><li>parent 项目中的 dependencyManagement 里的声明的依赖，只具有声明的作用，并不实现引入，因此子项目需要显式的声明需要用的依赖。如果不在子项目中声明依赖，是不会从父项目中继承下来的；只有在子项目中写了该依赖项，并且没有指定具体版本，才会从父项目中继承该项，并且 version 和 scope 都读取自父 pom；另外若子项目中指定了版本号，那么会使用子项目中指定的 jar 版本。</li> <li>parent 项目中的 dependencies 里声明的依赖会被所有的子项目继承。</li></ul> <h3 id="_5-2-spring-boot-starter"><a href="#_5-2-spring-boot-starter" class="header-anchor">#</a> 5.2 Spring Boot Starter</h3> <p>Spring Boot 非常优秀的地方在于提供了非常多以 spring-boot-starter-* 开头的开箱即用的 starter 启动器（依赖包），使得我们在开发业务代码时能够非常方便的、不需要过多关注框架的配置，而只需要关注业务即可。</p> <p>Spring Boot 在配置上相比 Spring 要简单许多，其核心在于 spring-boot-starter， 在使用 Spring Boot 来搭建一个项目时，只需要引入官方提供的 starter，就可以直接使用，免去了各种配置。</p> <p>官方目前已提供的常见的 Starter 如下 ：</p> <blockquote><p>spring-boot-starter：核心启动器，提供了自动配置，日志和 YAML 配置支持。</p> <p>spring-boot-starter-aop：支持使用 <code>Spring AOP</code> 和 <code>AspectJ</code> 进行切面编程。</p> <p>spring-boot-starter-freemarker：支持使用 <code>FreeMarker</code> 视图构建 Web 应用。</p> <p>spring-boot-starter-test：支持使用 <code>JUnit</code>，测试 <code>Spring Boot</code> 应用。</p> <p>spring-boot-starter-web：支持使用 <code>Spring MVC</code> 构建 Web 应用，包括 <code>RESTful</code> 应用，使用 <code>Tomcat</code> 作为默认的嵌入式容器。</p> <p>spring-boot-starter-actuator：支持使用 Spring Boot Actuator 提供生产级别的应用程序监控和管理功能。</p> <p>spring-boot-starter-logging：提供了对日志的支持，默认使用 Logback。</p></blockquote> <p>有关 Spring Boot Starter 命名规范，所有官方发布的 Starter 都遵循以下命名模式：<code>spring-boot-starter-*</code>，其中 <code>*</code> 指特定的应用程序代号或名称。任何第三方提供的 Starter 都不能以 <code>spring-boot</code> 作为前缀，应该将应用程序代号或名称作为前缀，譬如 <code>mybatis-spring-boot-starter</code>。</p> <h3 id="_5-3-web-启动器"><a href="#_5-3-web-启动器" class="header-anchor">#</a> 5.3 Web 启动器</h3> <p>这是 SpringBoot 提供的 Web 启动器，是一个快速集成 Web 模块的工具包，包含 Spring MVC，Jackson 相关的依赖，以及嵌入了 Tomcat9 服务器，默认端口 8080。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependencies</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependencies</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>需要注意的是，我们并没有在这里指定版本信息。因为 Spring Boot 的父工程已经对版本进行了管理了。</p> <p>这个时候，我们会发现项目中多出了大量的依赖：</p> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/decp.png" alt=""></p> <p>这些都是 Spring Boot 根据 spring-boot-starter-web 这个依赖自动引入的，而且所有的版本都已经管理好，不会出现冲突。</p> <h3 id="_5-4-打包独立运行"><a href="#_5-4-打包独立运行" class="header-anchor">#</a> 5.4 打包独立运行</h3> <p>对于 Spring Boot 项目来说无论是普通应用还是 Web 应用，其打包方式都是 jar 即可，当然 Web 应用也能打 war 包，但是需要额外添加许多插件来运行，比较麻烦。</p> <p>默认的 Maven 打包方式是不能正常的打包 Spring Boot 项目的，需要额外的引入打包插件，才能正常的对 Spring Boot 项目打包，以后只要拿到该 jar 包就能脱离 IDE 工具独立运行了。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- pom.xml 中添加插件 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>build</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugins</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- Spring Boot 打包插件 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugin</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-maven-plugin<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugin</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugins</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>build</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><ul><li>使用 maven 的 package 命令进行打包；</li> <li>使用命令 <code>java -jar xxx.jar</code> 运行 jar 包（--server.port=80）。</li></ul> <h2 id="六、spring-boot-参数配置"><a href="#六、spring-boot-参数配置" class="header-anchor">#</a> 六、Spring Boot 参数配置</h2> <h3 id="_6-1-参数来源"><a href="#_6-1-参数来源" class="header-anchor">#</a> 6.1 参数来源</h3> <ul><li>命令行启动项目时传入的参数，如：<code>java -jar xxx.jar --server.port=80</code>（一般给运维人员用的）；</li> <li>application.properties 或者 application.yml 文件（这个作为开发者用的最多）。</li> <li>自定义配置 properties 文件（这个用的相对少）。</li></ul> <p>一般用的比较多的就是直接在 <strong>application.properties</strong> 或者 <strong>application.yml</strong> 配置，其次是命令行启动方式。</p> <h4 id="_6-1-1-application-properties"><a href="#_6-1-1-application-properties" class="header-anchor">#</a> 6.1.1 application.properties</h4> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">server.port</span><span class="token punctuation">=</span><span class="token value attr-value">80</span>
<span class="token key attr-name">server.session-timeout</span><span class="token punctuation">=</span><span class="token value attr-value">30</span>
<span class="token key attr-name">server.tomcat.uri-encoding</span><span class="token punctuation">=</span><span class="token value attr-value">UTF-8</span>

<span class="token key attr-name">spring.datasource.driverClassName</span><span class="token punctuation">=</span><span class="token value attr-value">com.mysql.jdbc.Driver</span>
<span class="token key attr-name">spring.datasource.url</span><span class="token punctuation">=</span><span class="token value attr-value">jdbc:mysql://localhost:3306/rbac</span>
<span class="token key attr-name">spring.datasource.username</span><span class="token punctuation">=</span><span class="token value attr-value">root </span>
<span class="token key attr-name">spring.datasource.password</span><span class="token punctuation">=</span><span class="token value attr-value">admin</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h4 id="_6-1-2-application-yml"><a href="#_6-1-2-application-yml" class="header-anchor">#</a> 6.1.2 application.yml</h4> <div class="language-yml line-numbers-mode"><pre class="language-yml"><code><span class="token key atrule">server</span><span class="token punctuation">:</span>  
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">80</span>
  <span class="token key atrule">session-timeout</span><span class="token punctuation">:</span> <span class="token number">30</span>  
  <span class="token key atrule">tomcat.uri-encoding</span><span class="token punctuation">:</span> UTF<span class="token punctuation">-</span><span class="token number">8</span>  
  
<span class="token key atrule">spring</span><span class="token punctuation">:</span>  
  <span class="token key atrule">datasource</span><span class="token punctuation">:</span>  
    <span class="token key atrule">url</span><span class="token punctuation">:</span> jdbc<span class="token punctuation">:</span>mysql<span class="token punctuation">:</span>//localhost<span class="token punctuation">:</span>3306/crm  
    <span class="token key atrule">username</span><span class="token punctuation">:</span> root  
    <span class="token key atrule">password</span><span class="token punctuation">:</span> admin  
    <span class="token key atrule">driverClassName</span><span class="token punctuation">:</span> com.mysql.jdbc.Driver
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h3 id="_6-2-配置优先级-了解"><a href="#_6-2-配置优先级-了解" class="header-anchor">#</a> 6.2 配置优先级（了解）</h3> <p>一个项目中可以有多个配置文件存放在不同目录中，此时他们会遵循固定的优先级来处理有冲突的属性配置，优先级由高到底，高优先级的配置会覆盖低优先级的配置。用 application.properties 文件举例子，下面文件优先级由高到低排序：</p> <ul><li>项目/config/application.properties</li> <li>项目/application.properties</li> <li>classpath:config/application.properties</li> <li>classpath:application.properties</li></ul> <p>一般都在 <strong>classpath:application.properties</strong> 做配置，其他方式不使用。</p> <h3 id="_6-3-参数属性绑定"><a href="#_6-3-参数属性绑定" class="header-anchor">#</a> 6.3 参数属性绑定</h3> <p>通过配置参数，来自定义程序的运行。一般配置参数编写 application.properties 或者我们自定义的 properties 文件中。</p> <h4 id="_6-3-1-自定义的-properties"><a href="#_6-3-1-自定义的-properties" class="header-anchor">#</a> 6.3.1 自定义的 properties</h4> <p>回顾之前使用 XML 配置时，想让 Spring 知道我们指定自定义的 properties 文件，就需要如下配置：</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## db.properties</span>
<span class="token key attr-name">jdbc.driverClassName</span><span class="token punctuation">=</span><span class="token value attr-value">com.mysql.jdbc.Driver</span>
<span class="token key attr-name">jdbc.url</span><span class="token punctuation">=</span><span class="token value attr-value">jdbc:mysql://localhost:3306/rbac</span>
<span class="token key attr-name">jdbc.username</span><span class="token punctuation">=</span><span class="token value attr-value">root</span>
<span class="token key attr-name">jdbc.password</span><span class="token punctuation">=</span><span class="token value attr-value">admin</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">context:</span>property-placeholder</span> <span class="token attr-name">location</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>classpath:db.properties<span class="token punctuation">&quot;</span></span> <span class="token attr-name">system-properties-mode</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>NEVER<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>而现在使用 JavaConfig 配置，就得使用 <code>@PropertySource</code> + <code>@Value</code> 两个注解配合完成。<code>@PropertySource</code> 的作用就等价于上面那段 XML 配置。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">/**
 *  @PropertySource：把属性配置加载到 Spring 的环境对象中
 *  @Value：从 Spring 环境对象中根据 key 读取 value
 */</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@PropertySource</span><span class="token punctuation">(</span><span class="token string">&quot;classpath:db.properties&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.driverClassName}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> driverClassName<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.url}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> url<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.username}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.password}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">MyDataSource</span> <span class="token function">dataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">MyDataSource</span> dataSource <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyDataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setDriverClassName</span><span class="token punctuation">(</span>driverClassName<span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setUrl</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setUsername</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setPassword</span><span class="token punctuation">(</span>password<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> dataSource<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><h4 id="_6-3-2-默认application-properties"><a href="#_6-3-2-默认application-properties" class="header-anchor">#</a> 6.3.2 默认application.properties</h4> <p>准备好 application.properties 和一个类 MyDataSource，配置如下：</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## application.properties</span>
<span class="token key attr-name">jdbc.driverClassName</span><span class="token punctuation">=</span><span class="token value attr-value">com.mysql.jdbc.Driver</span>
<span class="token key attr-name">jdbc.url</span><span class="token punctuation">=</span><span class="token value attr-value">jdbc:mysql://localhost:3306/crm</span>
<span class="token key attr-name">jdbc.username</span><span class="token punctuation">=</span><span class="token value attr-value">root</span>
<span class="token key attr-name">jdbc.password</span><span class="token punctuation">=</span><span class="token value attr-value">admin</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyDataSource</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> driverClassName<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> url<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    
    <span class="token comment">// 省略 toString 方法</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p><strong>@Value 绑定单个属性</strong></p> <p>在自定义的类上绑定属性如下：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyDataSource</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.driverClassName}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> driverClassName<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.url}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> url<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.username}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.password}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>

    <span class="token comment">// 省略 toString 方法</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@Configuration</span> 
<span class="token annotation punctuation">@ComponentScan</span><span class="token punctuation">(</span><span class="token string">&quot;上面类所在的包路径&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>在配置类上绑定属性如下：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span> 
    <span class="token comment">// @Value：从 Spring 环境对象中根据 key 读取 value</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.driverClassName}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> driverClassName<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.url}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> url<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.username}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${jdbc.password}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">MyDataSource</span> <span class="token function">dataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">MyDataSource</span> dataSource <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyDataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setDriverClassName</span><span class="token punctuation">(</span>driverClassName<span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setUrl</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setUsername</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setPassword</span><span class="token punctuation">(</span>password<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> dataSource<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br></div></div><p><strong>@ConfigurationProperties 绑定对象属性</strong></p> <p>若觉得上面的方式比较笨重，可以把前缀编写到 <code>@ConfigurationProperties</code> 属性上，并且设置类属性与需要绑定的参数名相同，可实现自动绑定，但是<strong>注意</strong>，若是使用测试类加载贴有 <code>@Configuration</code> 的配置类，则需要在配置类中添加 <code>@EnableConfigurationProperties</code> 注解；若是使用测试类加载贴有 <code>@SpringBootApplication</code> 的配置类，则不需要。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@ToString</span>
<span class="token annotation punctuation">@Setter</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix<span class="token operator">=</span><span class="token string">&quot;jdbc&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyDataSource</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> driverClassName<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> url<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>或者像下面这样配置：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span><span class="token string">&quot;jdbc&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token class-name">MyDataSource</span> <span class="token function">dataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">MyDataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p><code>@EnableConfigurationProperties</code> 文档中解释：当 <code>@EnableConfigurationProperties</code> 注解应用到你的 <code>@Configuration</code> 时，任何贴 <code>@ConfigurationProperties</code> 注解的 beans 将自动被 Environment 进行属性绑定。</p> <h4 id="_6-3-3-environment-对象绑定属性"><a href="#_6-3-3-environment-对象绑定属性" class="header-anchor">#</a> 6.3.3 Environment 对象绑定属性</h4> <p>当要绑定的参数过多时，直接在配置类中注入 Spring 的 Environment 对象， 这样就不需要贴上在字段或者形参上太多的 <code>@Value</code> 注解，相对比较简洁。</p> <p>从 Environment 对象中可以获取到 <code>application.properties</code> 里面的参数</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>

<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JavaConfig</span> <span class="token punctuation">{</span>
    <span class="token comment">/**
     * environment：表示 Spring 的环境对象，该对象包含了加载的属性数据
     * 可以获取到 application.properties 里面的参数，也可以获取到 @PropertySource 中的参数
     * 但 application.properties 的优先级比 @PropertySource 高
     */</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">Environment</span> environment<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">MyDataSource</span> <span class="token function">dataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">MyDataSource</span> dataSource <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyDataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setDriverClassName</span><span class="token punctuation">(</span>environment<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">&quot;jdbc.driverClassName&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setUrl</span><span class="token punctuation">(</span>environment<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">&quot;jdbc.url&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setUsername</span><span class="token punctuation">(</span>environment<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">&quot;jdbc.username&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        dataSource<span class="token punctuation">.</span><span class="token function">setPassword</span><span class="token punctuation">(</span>environment<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">&quot;jdbc.password&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> dataSource<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div><h2 id="七、spring-boot-实战"><a href="#七、spring-boot-实战" class="header-anchor">#</a> 七、Spring Boot 实战</h2> <p>把之前的项目改造为 Spring Boot 项目。</p> <h3 id="_7-1-迁移-ssm-项目"><a href="#_7-1-迁移-ssm-项目" class="header-anchor">#</a> 7.1 迁移 ssm 项目</h3> <p><strong>快速创建 Spring Boot 项目</strong></p> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/image-20200401100210755-1704849648584.png" alt=""></p> <p><strong>添加依赖</strong></p> <p>如果是普通 Maven 项目，需要手动添加。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- 打包方式 jar 包 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>packaging</span><span class="token punctuation">&gt;</span></span>jar<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>packaging</span><span class="token punctuation">&gt;</span></span>

<span class="token comment">&lt;!-- 指定父工程 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.3.3.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependencies</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- spring boot Web 包 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- spring boot Test 包 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-test<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>test<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- Lombok --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.projectlombok<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>lombok<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>provided<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependencies</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div><p><strong>添加启动类</strong></p> <p>如果是普通 Maven 项目，需要手动添加。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RbacApplication</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">RbacApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="_7-2-配置数据库连接池"><a href="#_7-2-配置数据库连接池" class="header-anchor">#</a> 7.2 配置数据库连接池</h3> <h4 id="_7-2-1-添加依赖"><a href="#_7-2-1-添加依赖" class="header-anchor">#</a> 7.2.1 添加依赖</h4> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- MySQL 驱动 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>mysql<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>mysql-connector-java<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>runtime<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- Spring JDBC 和 TX --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-jdbc<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h4 id="_7-2-2-自动配置方式"><a href="#_7-2-2-自动配置方式" class="header-anchor">#</a> 7.2.2 自动配置方式</h4> <p>application.properties</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">spring.datasource.driver-class-name</span><span class="token punctuation">=</span><span class="token value attr-value">com.mysql.jdbc.Driver</span>
<span class="token key attr-name">spring.datasource.url</span><span class="token punctuation">=</span><span class="token value attr-value">jdbc:mysql:///rbac?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT%2B8&amp;useSSL=false</span>
<span class="token key attr-name">spring.datasource.username</span><span class="token punctuation">=</span><span class="token value attr-value">root</span>
<span class="token key attr-name">spring.datasource.password</span><span class="token punctuation">=</span><span class="token value attr-value">admin</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>此时运行测试获取的数据库连接池对象可以执行成功，并且我们看到了使用的连接池是 <strong>Hikari</strong>，全称是 Hikaricp。</p> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/image-20200401151114569-1704849648584.png" alt=""></p> <p>其实，在 Spring Boot 2.0 之后，采用的默认连接池就是 <strong>Hikari</strong>，号称“史上最快的连接池”，所以我们没有添加依赖也能直接用，Spring Boot 的自动配置中含有 DataSourceAutoConfiguration 配置类，会先检查容器中是否已经有连接池对象，没有则会使用默认的连接池，并根据特定的属性来自动配置连接池对象，用到的属性值来源于 DataSourceProperties 对象。</p> <h4 id="_7-2-3-配置-druid-连接池"><a href="#_7-2-3-配置-druid-连接池" class="header-anchor">#</a> 7.2.3 配置 Druid 连接池</h4> <p>当然如果我们在项目中还是想要使用 <strong>Druid</strong> 作为连接池也是可以的。只需要添加依赖即可，此时加的是 <strong>Druid</strong> 的 druid-spring-boot-starter 自动配置包， 里面包含了 DruidDataSourceAutoConfigure 自动配置类，会自动创建 Druid 的连接池对象，所以 Spring Boot 发现已经有连接池对象了，则不会再使用 <strong>Hikari</strong>。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- druid --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.alibaba<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>druid-spring-boot-starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.1.21<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/image-20200401154007897-1704849648584.png" alt=""></p> <p><strong>注意</strong>：如果添加的依赖是以前那种普通包，只有 Druid 自身的依赖，并不是自动配置包，则需要进行以下配置：</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.alibaba<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>druid<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.1.21<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">spring.datasource.type</span><span class="token punctuation">=</span><span class="token value attr-value">com.alibaba.druid.pool.DruidDataSource</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>所以一般如果已经提供了 Spring Boot 相关的自动配置包，直接使用自动配置的会更方便些。</p> <p>对于 <strong>Hikari</strong> 以及 <strong>Druid</strong> 两款都是开源产品，阿里的 Druid 有中文的开源社区，交流起来更加方便，并且经过阿里多个系统的实验，想必也是非常的稳定，而 Hikari 是 Spring Boot 2.0 默认的连接池，全世界使用范围也非常广，对于大部分业务来说，使用哪一款都是差不多的，毕竟性能瓶颈一般都不在连接池。</p> <h3 id="_7-3-集成-mybatis和pagehelper"><a href="#_7-3-集成-mybatis和pagehelper" class="header-anchor">#</a> 7.3 集成 MyBatis和PageHelper</h3> <h4 id="_7-3-1-拷贝项目代码"><a href="#_7-3-1-拷贝项目代码" class="header-anchor">#</a> 7.3.1 拷贝项目代码</h4> <ul><li>把 src\main\java 中的 java 代码全部拷贝到新项目中的 src\main\java 里面。</li> <li>把 src\main\resources 中存放 mapper.xml 的目录也拷贝到新项目中的 src\main\resources 里面。</li></ul> <p><strong>注意</strong>：按照下面步骤用什么拷贝什么。</p> <h4 id="_7-3-2-添加依赖"><a href="#_7-3-2-添加依赖" class="header-anchor">#</a> 7.3.2 添加依赖</h4> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- Mybatis 集成到 SpringBoot 中的依赖 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.mybatis.spring.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>mybatis-spring-boot-starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.3.1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!--分页插件--&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.github.pagehelper<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>pagehelper-spring-boot-starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.3.0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!--JSON转换的依赖--&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.alibaba<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>fastjson<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.2.83<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h4 id="_7-3-3-配置-mapper-对象"><a href="#_7-3-3-配置-mapper-对象" class="header-anchor">#</a> 7.3.3 配置 Mapper 对象</h4> <p><strong>扫描 Mapper 接口</strong>只要在配置类上贴个注解 <code>@MapperScan</code> 并指定扫描的包路径即可。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token annotation punctuation">@MapperScan</span><span class="token punctuation">(</span><span class="token string">&quot;cn.wolfcode.mapper&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SsmApplication</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">SsmApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h4 id="_7-3-4-配置属性"><a href="#_7-3-4-配置属性" class="header-anchor">#</a> 7.3.4 配置属性</h4> <p>在 application.properties 配置以前在 XML 配置了的那些 MyBatis 的属性，属性前缀 mybatis。</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## 配置别名</span>
<span class="token key attr-name">mybatis.type-aliases-package</span><span class="token punctuation">=</span><span class="token value attr-value">cn.wolfcode.domain</span>

<span class="token comment">## 打印 SQL 日志</span>
<span class="token key attr-name">logging.level.cn.wolfcode.mapper</span><span class="token punctuation">=</span><span class="token value attr-value">trace</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>添加分页相关的配置</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">pagehelper.reasonable</span><span class="token punctuation">=</span><span class="token value attr-value">true</span>
<span class="token key attr-name">pagehelper.helper-dialect</span><span class="token punctuation">=</span><span class="token value attr-value">mysql</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h3 id="_7-4-事务管理"><a href="#_7-4-事务管理" class="header-anchor">#</a> 7.4 事务管理</h3> <h4 id="_7-4-1-xml方式-了解"><a href="#_7-4-1-xml方式-了解" class="header-anchor">#</a> 7.4.1 XML方式（了解）</h4> <p>采取配置类和 XML 混用的策略，在配置类上使用 @ImportResource(&quot;classpath:spring-tx.xml&quot;)。</p> <h4 id="_7-4-2-注解方式"><a href="#_7-4-2-注解方式" class="header-anchor">#</a> 7.4.2 注解方式</h4> <p>直接在<strong>业务层实现类上或者其方法</strong>上直接贴 <code>@Transactional</code> 注解即可。</p> <p>Spring Boot 自动配置中提供了 TransactionAutoConfiguration 事务注解自动配置类，引入了事务的依赖后，可直接使用 <code>@Transactional</code> 注解。</p> <h4 id="_7-4-3-配置代理实现"><a href="#_7-4-3-配置代理实现" class="header-anchor">#</a> 7.4.3 配置代理实现</h4> <p>Spring Boot 默认优先选择 CGLIB 代理，如果需要改为优先使用 JDK 代理，需要做以下配置：</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">spring.aop.proxy-target-class</span><span class="token punctuation">=</span><span class="token value attr-value">false</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h4 id="_7-4-4-测试验证"><a href="#_7-4-4-测试验证" class="header-anchor">#</a> 7.4.4 测试验证</h4> <p>在测试类上添加方法，打印业务对象看下其真实类型。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">testSave</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>departmentService<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h3 id="_7-5-集成-web"><a href="#_7-5-集成-web" class="header-anchor">#</a> 7.5 集成 Web</h3> <h4 id="_7-5-1-添加依赖"><a href="#_7-5-1-添加依赖" class="header-anchor">#</a> 7.5.1 添加依赖</h4> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!-- spring boot web 启动器（之前已添加了） --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h4 id="_7-5-2-修改端口"><a href="#_7-5-2-修改端口" class="header-anchor">#</a> 7.5.2 修改端口</h4> <p>在 application.properties 配置，如下：</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">server.port</span><span class="token punctuation">=</span><span class="token value attr-value">80</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h4 id="_7-5-3-静态资源处理"><a href="#_7-5-3-静态资源处理" class="header-anchor">#</a> 7.5.3 静态资源处理</h4> <ul><li>默认情况下，Spring Boot 会从 classpath 下的 /static，/public，/resources，/META-INF/resources 下加载静态资源。</li> <li>可以在 application.properties 中配置 spring.resources.staticLocations 属性来修改静态资源加载地址。</li> <li>因为应用是打成 jar 包，所以之前的 src/main/webapp 就作废了，如果有文件上传，那么就的必须去配置图片所在的路径。</li></ul> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## 告诉 Spring Boot 什么访问的路径是找静态资源</span>
<span class="token key attr-name">spring.resources.static-locations</span><span class="token punctuation">=</span><span class="token value attr-value">classpath:/bb</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h3 id="_7-6-集成-jsp"><a href="#_7-6-集成-jsp" class="header-anchor">#</a> 7.6 集成 JSP</h3> <p>官方并不推荐使用JSP</p> <p>https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.servlet.spring-mvc.binding-initializer</p> <h4 id="_7-6-1-添加依赖"><a href="#_7-6-1-添加依赖" class="header-anchor">#</a> 7.6.1 添加依赖</h4> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token comment">&lt;!--JSP 解析引擎--&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.apache.tomcat.embed<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>tomcat-embed-jasper<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>provided<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>javax.servlet<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>jstl<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>provided<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h4 id="_7-6-2-定义jsp存储目录"><a href="#_7-6-2-定义jsp存储目录" class="header-anchor">#</a> 7.6.2 定义JSP存储目录</h4> <p>在<code>src/main/webapp/WEB-INF/views/</code>目录下定义JSP文件，将项目的JSP文件拷贝到这个目录</p> <p>需要在pom.xml中定义JSP文件的编译目录</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>build</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugins</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- Spring Boot 打包插件，插件版本不能太高，否则会出现访问404的问题 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugin</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-maven-plugin<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.4.2.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugin</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugins</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>resources</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 打包时将jsp文件拷贝到META-INF目录下--&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>resource</span><span class="token punctuation">&gt;</span></span>
            <span class="token comment">&lt;!-- 指定resources插件处理哪个目录下的资源文件 --&gt;</span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>directory</span><span class="token punctuation">&gt;</span></span>src/main/webapp<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>directory</span><span class="token punctuation">&gt;</span></span>
            <span class="token comment">&lt;!-- 注意必须要放在此目录下才能被访问到 --&gt;</span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>targetPath</span><span class="token punctuation">&gt;</span></span>META-INF/resources<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>targetPath</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>includes</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>include</span><span class="token punctuation">&gt;</span></span>**/**<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>include</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>includes</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>resource</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>resource</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>directory</span><span class="token punctuation">&gt;</span></span>src/main/resources<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>directory</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>includes</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>include</span><span class="token punctuation">&gt;</span></span>**/**<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>include</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>includes</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>filtering</span><span class="token punctuation">&gt;</span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>filtering</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>resource</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>resources</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>build</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div><h4 id="_7-6-3-相关配置"><a href="#_7-6-3-相关配置" class="header-anchor">#</a> 7.6.3 相关配置</h4> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">spring.mvc.view.prefix</span><span class="token punctuation">=</span><span class="token value attr-value">/WEB-INF/views/</span>
<span class="token key attr-name">spring.mvc.view.suffix</span><span class="token punctuation">=</span><span class="token value attr-value">.jsp</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h4 id="_7-6-4-controller配置"><a href="#_7-6-4-controller配置" class="header-anchor">#</a> 7.6.4 Controller配置</h4> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Controller</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/dept&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DepartmentController</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">IDeaprtmentService</span> deaprtmentService<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/list&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">list</span><span class="token punctuation">(</span><span class="token class-name">QueryObject</span> qo<span class="token punctuation">,</span> <span class="token class-name">Model</span> model<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">PageInfo</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Department</span><span class="token punctuation">&gt;</span></span> pageInfo <span class="token operator">=</span> deaprtmentService<span class="token punctuation">.</span><span class="token function">selectList</span><span class="token punctuation">(</span>qo<span class="token punctuation">)</span><span class="token punctuation">;</span>
        model<span class="token punctuation">.</span><span class="token function">addAttribute</span><span class="token punctuation">(</span><span class="token string">&quot;pageInfo&quot;</span><span class="token punctuation">,</span>pageInfo<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//返回视图名称即可</span>
        <span class="token keyword">return</span> <span class="token string">&quot;dept_list&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h3 id="_7-7-统一异常处理"><a href="#_7-7-统一异常处理" class="header-anchor">#</a> 7.7 统一异常处理</h3> <h4 id="_7-7-1-框架自带方式"><a href="#_7-7-1-框架自带方式" class="header-anchor">#</a> 7.7.1 框架自带方式</h4> <p>Spring Boot 默认情况下，会把所有错误都交给 BasicErrorController 类完成处理，错误的视图导向到 <strong>classpath:/static/error/ 和 classpath:/templates/error/</strong> 路径上，HTTP 状态码就是默认视图的名称。如：</p> <ul><li>出现 404 错误 -&gt; classpath:/static/error/404.html</li> <li>出现 5xx 错误 -&gt; classpath:/static/error/5xx.html</li></ul> <h4 id="_7-7-2-控制器增强器方式"><a href="#_7-7-2-控制器增强器方式" class="header-anchor">#</a> 7.7.2 控制器增强器方式</h4> <p>自己定义一个控制器增强器，专门用于统一异常处理，该方式一般用于 5xx 类错误。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@ControllerAdvice</span> <span class="token comment">// 控制器增强器</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ExceptionControllerAdvice</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span><span class="token class-name">RuntimeException</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token comment">// 处理什么类型的异常</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">handlException</span><span class="token punctuation">(</span><span class="token class-name">RuntimeException</span> e<span class="token punctuation">,</span> <span class="token class-name">Model</span> model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 记得这行代码保留，不然项目后台出异常，开发工具控制台看不多错误信息</span>
        <span class="token keyword">return</span> <span class="token string">&quot;errorView&quot;</span><span class="token punctuation">;</span> <span class="token comment">// 指定错误页面视图名称</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h3 id="_7-8-添加拦截器"><a href="#_7-8-添加拦截器" class="header-anchor">#</a> 7.8 添加拦截器</h3> <p>在传统的 XML 方式中，我们需要在 <code>&lt;mvc：interceptors&gt;</code> 标签中去注册我们自定义的拦截器。在 Spring Boot 中，提供了 WebMvcConfigurer 配置接口，是使用 JavaConfig 配置 Spring MVC 的标准，如果我们需要对 Spring MVC 做配置，则需要让我们自定义配置类实现该接口，若是需要注册拦截器，则实现接口中的 addInterceptors 方法即可。</p> <h4 id="_7-8-1-编写拦截器"><a href="#_7-8-1-编写拦截器" class="header-anchor">#</a> 7.8.1 编写拦截器</h4> <p>让 Spring 管理拦截器 bean 对象，在拦截器类上贴 <code>@Component</code> 注解。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LoginInterceptor</span> <span class="token keyword">implements</span> <span class="token class-name">HandlerInterceptor</span> <span class="token punctuation">{</span> 
    <span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PermissionInterceptor</span> <span class="token keyword">implements</span> <span class="token class-name">HandlerInterceptor</span> <span class="token punctuation">{</span>
    <span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h4 id="_7-8-2-配置义拦截器"><a href="#_7-8-2-配置义拦截器" class="header-anchor">#</a> 7.8.2 配置义拦截器</h4> <p>定义一个配置类，实现 WebMvcConfigurer 接口，在 addInterceptors 方法注册拦截器。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MvcJavaConfig</span> <span class="token keyword">implements</span> <span class="token class-name">WebMvcConfigurer</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">LoginInterceptor</span> loginInterceptor<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">PermissionInterceptor</span> permissionInterceptor<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addInterceptors</span><span class="token punctuation">(</span><span class="token class-name">InterceptorRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 注册登录拦截器</span>
        registry<span class="token punctuation">.</span><span class="token function">addInterceptor</span><span class="token punctuation">(</span>loginInterceptor<span class="token punctuation">)</span>
            <span class="token comment">// 对哪些资源起过滤作用</span>
            <span class="token punctuation">.</span><span class="token function">addPathPatterns</span><span class="token punctuation">(</span><span class="token string">&quot;/**&quot;</span><span class="token punctuation">)</span>
            <span class="token comment">// 对哪些资源起排除作用</span>
            <span class="token punctuation">.</span><span class="token function">excludePathPatterns</span><span class="token punctuation">(</span><span class="token string">&quot;/login&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;/static/**&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// 注册登录拦截器</span>
        registry<span class="token punctuation">.</span><span class="token function">addInterceptor</span><span class="token punctuation">(</span>permissionInterceptor<span class="token punctuation">)</span>
            <span class="token comment">// 对哪些资源起过滤作用</span>
            <span class="token punctuation">.</span><span class="token function">addPathPatterns</span><span class="token punctuation">(</span><span class="token string">&quot;/**&quot;</span><span class="token punctuation">)</span>
            <span class="token comment">// 对哪些资源起排除作用</span>
            <span class="token punctuation">.</span><span class="token function">excludePathPatterns</span><span class="token punctuation">(</span><span class="token string">&quot;/login&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;/static/**&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div><h2 id="八、系统日志"><a href="#八、系统日志" class="header-anchor">#</a> 八、系统日志</h2> <h3 id="_8-1-为什么要用日志"><a href="#_8-1-为什么要用日志" class="header-anchor">#</a> 8.1 为什么要用日志</h3> <ul><li>比起 System.out.println，日志框架更为灵活，可以把日志的输出和代码分离。</li> <li>日志框架可以方便的定义日志的输出环境，控制台，文件，数据库。</li> <li>日志框架可以方便的定义日志的输出格式和输出级别。</li></ul> <h3 id="_8-2-spring-boot-中的日志介绍"><a href="#_8-2-spring-boot-中的日志介绍" class="header-anchor">#</a> 8.2 Spring Boot 中的日志介绍</h3> <ul><li>Spring Boot 默认已经开启日志，其默认的日志格式为：时间 日志级别 线程ID 线程名称 日志类 日志说明。</li> <li>Spring Boot 的日志分为：系统日志和应用日志。</li> <li>日志级别，级别越高，输出的内容越少，如果设置的级别为 info，则 debug 以及 trace 级别的都无法显示，日志级别由低到高 trace &lt; debug &lt; info &lt; warn &lt; error。</li> <li>Spring Boot 默认选择 Logback 作为日志框架，也能选择其他日志框架，但是没有必要。</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/20180503123846653-1704849648584.png" alt=""></p> <h3 id="_8-3-输出日志"><a href="#_8-3-输出日志" class="header-anchor">#</a> 8.3 输出日志</h3> <p>在我们自定义的类中可以使用日志框架来输出。</p> <p><strong>方式一</strong></p> <p>在类中定义一个静态 Logger 对象，传入当前类的作用是方便输出日志时可以清晰地看到该日志信息是属于哪个类的。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">Logger</span> log <span class="token operator">=</span> <span class="token class-name">LoggerFactory</span><span class="token punctuation">.</span><span class="token function">getLogger</span><span class="token punctuation">(</span>当前类<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><strong>方式二</strong></p> <p>使用 Lombok 提供的 @Slf4j 注解来简化代码，其实和方式一的作用是一样的。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Slf4j</span>
<span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PermissionServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">IPermissionService</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>在需要输出日志的地方使用日志的输出方法</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code>log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
log<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token comment">// 输出日志中有变量可以使用 {} 作为占位符</span>
log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;删除id为{}的数据&quot;</span>， id<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h3 id="_8-4-日志级别"><a href="#_8-4-日志级别" class="header-anchor">#</a> 8.4 日志级别</h3> <p>我们来尝试一下日志级别：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code>log<span class="token punctuation">.</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string">&quot;权限插入成功：{}&quot;</span>，expression<span class="token punctuation">)</span><span class="token punctuation">;</span>
log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;权限插入成功：{}&quot;</span>，expression<span class="token punctuation">)</span><span class="token punctuation">;</span>
log<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token string">&quot;权限插入成功：{}&quot;</span>，expression<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>执行权限加载功能后，发现控制台出现 info 与 warn 的信息，debug 的没有显示，原因是因为 Spring Boot 默认的日志级别是 info，所以 debug 低于 info 级别，就不会显示出来了。</p> <p><strong><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/image-20240110162738975.png" alt=""></strong></p> <p>若要修改日志级别，最快速的方式是在 application.properties 配置，配置如下</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## 把日志级别修改为 debug，不过我们一般不会更改，除非要调试找 bug，不然控制台显示的内容太多也容易乱</span>
<span class="token key attr-name">logging.level.root</span><span class="token punctuation">=</span><span class="token value attr-value">debug</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h3 id="_8-5-logback-配置文件的使用"><a href="#_8-5-logback-配置文件的使用" class="header-anchor">#</a> 8.5 Logback 配置文件的使用</h3> <p>Logback 框架默认会自动加载 classpath:logback.xml，作为框架的配置文件，在 Spring Boot 中使用时，还会额外的支持自动加载classpath:logback-spring.xml，在 Spring Boot 中推荐使用 logback-spring.xml，功能更强大些。</p> <p>样板文件：</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token prolog">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="token comment">&lt;!--
    scan：开启日志框架的热部署，默认值 true 表示开启
    scanPeriod：热部署的频率，默认值 60 second
    debug：设置输出框架内部的日志，默认值 false
--&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>configuration</span> <span class="token attr-name">scan</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>true<span class="token punctuation">&quot;</span></span> <span class="token attr-name">scanPeriod</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>60 second<span class="token punctuation">&quot;</span></span> <span class="token attr-name">debug</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>false<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>appName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>springboot demo<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>contextName</span><span class="token punctuation">&gt;</span></span>${appName}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>contextName</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!--日志输出到控制台--&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>STDOUT<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ch.qos.logback.core.ConsoleAppender<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>encoder</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>pattern</span><span class="token punctuation">&gt;</span></span>%d{yyyy-MM-dd-HH：mm：ss} %level [%thread]-%logger{35} &gt;&gt; %msg %n<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>pattern</span><span class="token punctuation">&gt;</span></span>
　　　　<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>encoder</span><span class="token punctuation">&gt;</span></span>
　　 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>appender</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!--日志输出到文件--&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ROLLING_FILE<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ch.qos.logback.core.rolling.RollingFileAppender<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 指定日志文件输出格式 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>layout</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ch.qos.logback.classic.PatternLayout<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>pattern</span><span class="token punctuation">&gt;</span></span>%-4relative [%thread] %level %logger{35} - %msg %n<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>pattern</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>layout</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 指定日志文件存放路径 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>file</span><span class="token punctuation">&gt;</span></span>./logs/myapp.log<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>file</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 指定最大备份索引数，即最多保留多少个历史日志文件 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>rollingPolicy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>fileNamePattern</span><span class="token punctuation">&gt;</span></span>./logs/myapp.log.%d{yyyy-MM-dd}.%i.gz<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>fileNamePattern</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>maxFileSize</span><span class="token punctuation">&gt;</span></span>10MB<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>maxFileSize</span><span class="token punctuation">&gt;</span></span> <span class="token comment">&lt;!-- 单个日志文件大小 --&gt;</span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>maxHistory</span><span class="token punctuation">&gt;</span></span>7<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>maxHistory</span><span class="token punctuation">&gt;</span></span> <span class="token comment">&lt;!-- 最多保留7个历史日志文件 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>rollingPolicy</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>appender</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!--
        root 是项目通用的 logger，一般情况下都是使用 root 配置的日志输出
        level：按照级别输出日志，日志级别，级别越高，输出的内容越少
    --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>root</span> <span class="token attr-name">level</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>debug<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>STDOUT<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>appender-ref</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ROLLING_FILE<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>root</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>configuration</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br></div></div><p>参考日志格式：</p> <ul><li>%d{yyyy-MM-dd-HH：mm：ss} %level [%thread]-%class：%line &gt;&gt; %msg %n</li></ul> <p>格式中的标识符组成：</p> <ul><li>%logger{n}：输出 Logger 对象类名，n 代表长度</li> <li>%class{n}：输出所在类名</li> <li>%d{pattern} 或者 date{pattern}：输出日志日期，格式同 Java</li> <li>%L/line：日志所在行号</li> <li>%m/msg：日志内容</li> <li>%method：所在方法名称</li> <li>%p/level：日志级别</li> <li>%thread：所在线程名称</li></ul> <h2 id="九、其他功能"><a href="#九、其他功能" class="header-anchor">#</a> 九、其他功能</h2> <h3 id="_9-1-修改-banner"><a href="#_9-1-修改-banner" class="header-anchor">#</a> 9.1 修改 banner</h3> <p>Spring Boot 提供了一些扩展点，比如修改 banner：在 resources 根目录中放入 banner.txt 文件，替换默认的 banner。</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## application.properties</span>
<span class="token comment">## 关闭 banner</span>
<span class="token key attr-name">spring.main.banner-mode</span><span class="token punctuation">=</span><span class="token value attr-value">off </span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h3 id="_9-2-切换运行环境"><a href="#_9-2-切换运行环境" class="header-anchor">#</a> 9.2 切换运行环境</h3> <p>在实际开发中，一个系统是有多套运行环境的，如开发时有开发的环境，测试时有测试的环境，不同的环境中，系统的参数设置是不同的，如：连接开发数据和测试数据库的 URL 绝对是不同的，那么怎么快速的切换系统运行的环境呢？我们需要为不同的环境创建不同的配置文件，如下：</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## application-dev.properties</span>
<span class="token key attr-name">server.port</span><span class="token punctuation">=</span><span class="token value attr-value">8081</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## application-test.properties</span>
<span class="token key attr-name">server.port</span><span class="token punctuation">=</span><span class="token value attr-value">8082</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token comment">## 在 application.properties 中指定需要使用的环境即可</span>
<span class="token key attr-name">spring.profiles.active</span><span class="token punctuation">=</span><span class="token value attr-value">dev </span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h2 id="十、spring-boot-自动配置原理"><a href="#十、spring-boot-自动配置原理" class="header-anchor">#</a> 十、Spring Boot 自动配置原理</h2> <p>使用 Spring Boot 之后，做一个整合了 Spring MVC 的 Web 工程开发，变的无比简单，那些繁杂的配置都消失不见了，这是如何做到的？一切魔力的开始，都是从我们的 main 函数来的，所以我们再次来看下启动类：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DemoApplication</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">DemoApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>从上面代码我们发现特别的地方有两个：</p> <ul><li>注解：<code>@SpringBootApplication</code>；</li> <li>run方法：SpringApplication.run()。</li></ul> <h3 id="_10-1-springbootapplication"><a href="#_10-1-springbootapplication" class="header-anchor">#</a> 10.1 @SpringBootApplication</h3> <p>点击进入，查看源码：
<img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/1525488226710-1704849648583.png" alt=""></p> <p>这里重点的注解有3个：</p> <ul><li>@SpringBootConfiguration</li> <li>@EnableAutoConfiguration</li> <li>@ComponentScan</li></ul> <h4 id="_10-1-1-springbootconfiguration"><a href="#_10-1-1-springbootconfiguration" class="header-anchor">#</a> 10.1.1 @SpringBootConfiguration</h4> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/1525488518514-1704849648583.png" alt=""></p> <p>通过这段我们可以看出，在这个注解上面，又有一个 <code>@Configuration</code> 注解。通过上面的注释阅读我们知道：这个注解的作用就是声明当前类是一个配置类，然后 Spring 会自动扫描到添加了 <code>@Configuration</code> 的类，并且读取其中的配置信息。而 <code>@SpringBootConfiguration</code> 是来声明当前类是 Spring Boot 应用的配置类，项目中只能有一个。所以一般我们无需自己添加。</p> <h4 id="_10-1-2-componentscan"><a href="#_10-1-2-componentscan" class="header-anchor">#</a> 10.1.2 @ComponentScan</h4> <p>我们的 @SpringBootApplication 注解声明的类就是 main 函数所在的启动类，因此扫描的包是该类所在包及其子包。因此，<strong>一般启动类会放在一个比较前的包目录中。</strong></p> <h4 id="_10-1-3-enableautoconfiguration"><a href="#_10-1-3-enableautoconfiguration" class="header-anchor">#</a> 10.1.3 @EnableAutoConfiguration</h4> <p><code>@EnableAutoConfiguration</code> 的作用，告诉 Spring Boot 基于你所添加的依赖，去“猜测”你想要如何配置 Spring。比如我们引入了 <code>spring-boot-starter-web</code>，而这个启动器中帮我们添加了 <code>tomcat</code>、<code>SpringMVC</code> 的依赖。此时自动配置就知道你是要开发一个 Web 应用，所以就帮你完成了 Web 及 Spring MVC 的默认配置了！</p> <p>Spring Boot 内部对大量的第三方库或 Spring 内部库进行了默认配置，这些配置是否生效，取决于我们是否引入了对应库所需的依赖，如果有，那么默认配置就会生效。那么带来新的问题，如下：</p> <ul><li>这些默认配置是在哪里定义的呢？</li> <li>为何依赖引入就会触发配置呢？</li></ul> <h3 id="_10-2-如何自动配置"><a href="#_10-2-如何自动配置" class="header-anchor">#</a> 10.2 如何自动配置</h3> <p><code>@EnableAutoConfiguration</code> 注解中导入了一个 AutoConfigurationImportSelector 配置类，该类中有个 getCandidateConfigurations 方法，方法的作用是委托 SpringFactoriesLoader 去读取 jar 包中的 META-INF/spring.factories 文件，并加载里面配置的自动配置对象，包括：AOP，PropertyPlaceholder，FreeMarker，HttpMessageConverter，Jackson，DataSourceDataSourceTransactionManager，DispatcherServlet 等等。</p> <p>其实在我们的项目中，已经自动引入了一个依赖：spring-boot-autoconfigure，上面说到的这些自动配置类，都来自该包。</p> <p>虽然 spring.factories 文件中定义了很多配置类，但并不是所有配置类都会生效，只有符合条件的是才会自动装配。</p> <p>我们来看一个我们熟悉的，例如 Spring MVC，查看其自动配置类：</p> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/1525499859426-1704849648583.png" alt=""></p> <p>打开 WebMvcAutoConfiguration：</p> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/20240310233235.png" alt=""></p> <p>我们看到这个类上的 4 个注解：</p> <ul><li><p><code>@Configuration</code>：声明这个类是一个配置类</p></li> <li><p><code>@ConditionalOnWebApplication(type = Type.SERVLET)</code></p></li></ul> <p>ConditionalOn，翻译就是在某个条件下，此处就是满足项目的类是是 Type.SERVLET 类型，我们现在的项目就满足了，就是一个 Web 工程。</p> <ul><li><code>@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })</code></li></ul> <p>这里的条件是 OnClass，也就是满足以下类存在：Servlet、DispatcherServlet、WebMvcConfigurer。这里就是判断你是否引入了 Spring MVC相关依赖，引入依赖后该条件成立，当前类的配置才会生效！</p> <ul><li><code>@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)</code></li></ul> <p>这个条件与上面不同，OnMissingBean，是说环境中没有指定的 bean 这个才生效。其实这就是自定义配置的入口，也就是说，如果我们自己配置了一个 WebMVCConfigurationSupport 的 bean，代表容器里已经存在该 bean 了，那么这个默认配置就会失效！</p> <p>接着，我们查看 WebMvcAutoConfiguration 该类中定义了什么：</p> <p>视图解析器：</p> <p><img src="https://cdn.jsdelivr.net/gh/langfeiyes/images-khub/1525500405278-1704849648584.png" alt=""></p> <p>WebMvcAutoConfiguration 中使用了 <code>@AutoConfigureAfter</code> 注解，意为指定的类加载完了后，再加载本类。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@AutoConfigureAfter</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token class-name">DispatcherServletAutoConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">TaskExecutionAutoConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">ValidationAutoConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>而 DispatcherServletAutoConfiguration 中又做了很多事情，比如配置了前端控制器：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token constant">DEFAULT_DISPATCHER_SERVLET_BEAN_NAME</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token class-name">DispatcherServlet</span> <span class="token function">dispatcherServlet</span><span class="token punctuation">(</span><span class="token class-name">WebMvcProperties</span> webMvcProperties<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">DispatcherServlet</span> dispatcherServlet <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DispatcherServlet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    dispatcherServlet<span class="token punctuation">.</span><span class="token function">setDispatchOptionsRequest</span><span class="token punctuation">(</span>webMvcProperties<span class="token punctuation">.</span><span class="token function">isDispatchOptionsRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    dispatcherServlet<span class="token punctuation">.</span><span class="token function">setDispatchTraceRequest</span><span class="token punctuation">(</span>webMvcProperties<span class="token punctuation">.</span><span class="token function">isDispatchTraceRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    dispatcherServlet<span class="token punctuation">.</span><span class="token function">setPublishEvents</span><span class="token punctuation">(</span>webMvcProperties<span class="token punctuation">.</span><span class="token function">isPublishRequestHandledEvents</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    dispatcherServlet<span class="token punctuation">.</span><span class="token function">setEnableLoggingRequestDetails</span><span class="token punctuation">(</span>webMvcProperties<span class="token punctuation">.</span><span class="token function">isLogRequestDetails</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> dispatcherServlet<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><h3 id="_10-3-总结"><a href="#_10-3-总结" class="header-anchor">#</a> 10.3 总结</h3> <ul><li><code>@SpringBootApplication</code> 注解内部是3大注解功能的集成
<ul><li><code>@ComponentScan</code>：开启组件扫描</li> <li><code>@SpringBootConfiguration</code>：作用等同于 <code>@Configuration</code> 注解，也是用于标记配置类</li> <li><code>@EnableAutoConfiguration</code>：内部导入 AutoConfigurationImportSelector，该类中有个 getCandidateConfigurations 方法，读取 jar 包中 META-INF/spring.factories 文件中配置类，再根据条件进行加载和配置，比如：AOP，PropertyPlaceholder，FreeMarker，HttpMessageConverter，Jackson，DataSourceDataSourceTransactionManager，DispatcherServlet，WebMvc 等等</li></ul></li> <li>SpringApplication.run(..)的作用
<ul><li>启动 Spring Boot 应用</li> <li>加载自定义的配置类，完成自动配置功能</li> <li>把当前项目配置到嵌入的 Tomcat 服务器</li> <li>启动嵌入的 Tomcat 服务器</li></ul></li></ul> <h2 id="十一、小结与作业"><a href="#十一、小结与作业" class="header-anchor">#</a> 十一、小结与作业</h2> <ul><li>掌握JavaConfig配置方式</li> <li>SpringBoot实现IOC、DI操作</li> <li>掌握SpringBoot入门案例</li> <li>掌握SpringBoot参数配置与获取</li> <li>掌握SpringBoot与各种框架集成</li> <li>掌握SpringBoot系统日志操作</li> <li>掌握SpringBoot自动配置原理</li></ul></div></div>  <div class="page-edit"><!----> <div class="tags"><a href="/tags/?tag=SpringBoot" title="标签">#SpringBoot</a></div> <!----></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/pages/4ab4d3/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">项目实战-SSM整合</div></a> <a href="/pages/9234b6/" class="page-nav-centre page-nav-centre-next"><div class="tooltip">ECMAScript6</div></a></div> <div class="page-nav"><p class="inner"><span class="prev">
        ←
        <a href="/pages/4ab4d3/" class="prev">项目实战-SSM整合</a></span> <span class="next"><a href="/pages/9234b6/">ECMAScript6</a>→
      </span></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/pages/0c07b2/"><div>
            IT杂货铺
            <!----></div></a> <span class="date">03-23</span></dt></dl><dl><dd>02</dd> <dt><a href="/pages/705b35/"><div>
            人事百问
            <!----></div></a> <span class="date">03-22</span></dt></dl><dl><dd>03</dd> <dt><a href="/pages/78eb56/"><div>
            MyBatis-Plus
            <!----></div></a> <span class="date">03-12</span></dt></dl> <dl><dd></dd> <dt><a href="/archives/" class="more">更多文章&gt;</a></dt></dl></div></div></main></div> <div class="footer"><div class="icons"><a href="mailto:langfeiyes@163.com" title="发邮件" target="_blank" class="iconfont icon-youjian"></a><a href="https://github.com/langfeiyes" title="GitHub" target="_blank" class="iconfont icon-github"></a><a href="https://music.163.com/#/playlist?id=755597173" title="听音乐" target="_blank" class="iconfont icon-erji"></a></div> 
  Theme by
  <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a> 
    | Copyright © 2024-2024
    <span><a href="https://beian.miit.gov.cn/" target="_blank">粤ICP备18007927号-1</a></span></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">
          跟随系统
        </li><li class="iconfont icon-rijianmoshi">
          浅色模式
        </li><li class="iconfont icon-yejianmoshi">
          深色模式
        </li><li class="iconfont icon-yuedu">
          阅读模式
        </li></ul></div></div> <!----> <!----> <!----></div><div class="global-ui"><div></div></div></div>
    <script src="/assets/js/app.a2a00aa5.js" defer></script><script src="/assets/js/2.256f807a.js" defer></script><script src="/assets/js/53.4110ef1e.js" defer></script>
  </body>
</html>
